package com.study.www.config;

import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;

import java.net.InetAddress;
import java.net.NetworkInterface;

/**
 * @author : 89007337.zhuyanpeng
 * @date :Create in  2019/8/19- 22:23
 **/
public class IdWorks {

    //理论上每一毫秒可以有 50000 个数
    private final  static int MILLISECOND = 50000;
    //毫秒内自增位数
    private volatile static int sequenceBits = 1;
    //上次生成id的时间戳
    private volatile static long lastTimestamp = -1L;
    // 网卡后6位
    private volatile static String mac=null;
    // 时间起始标记点，作为基准，一般取系统的最近时间（一旦确定不能变动）
    //20101231
    private final static long twepoch = 1293724800000L;


    public synchronized static String getId() {
        long nowTimeStamp = System.currentTimeMillis() - twepoch;
        getHostIp();
        //当前时间等于上次时间
        if (nowTimeStamp != lastTimestamp) {
            //当前时间不等于上一次时间
            lastTimestamp = nowTimeStamp;
            //归档时间
            resetSequence();
        }else{
            //当前时间等于上次时间
            if (MILLISECOND == sequenceBits) {
                //当前次数已经达到统计上限的次数 则当前方法被失效
                throw  new RuntimeException("the steps is MAX->"+MILLISECOND);
            }
        }
        //取毫秒内自增数并+1\\
        String s = nowTimeStamp + IdWorks.mac + getSequence();
        while (s == null){
          return   getId();
        }
        return s;
    }

    private static String getSequence() {
        String str = String.format("%05d", sequenceBits);
        sequenceBits++;
        return str;
    }

    private static void resetSequence() {
        sequenceBits = 1;
    }

    private static void getHostIp(){
        if (IdWorks.mac != null){
            return;
        }
        String str= null;
        do{
            str=String.format("%06d", RandomUtils.nextInt());
        }
        while (str ==null);
        try{
            byte[] hardwareAddress = NetworkInterface.getByInetAddress(InetAddress.getLocalHost()).getHardwareAddress();
            StringBuilder stringBuilder = new StringBuilder();
            for (byte address : hardwareAddress) {
                stringBuilder.append(Math.abs(address));
            }
            Integer integer = Integer.valueOf(stringBuilder.toString());
            integer = integer % 100000;
            String format = String.format("%06d", integer);
            if (StringUtils.isNotBlank(format)) {
                str=format;
            }
            IdWorks.mac = str;
        } catch(Exception e){}
    }

}
